package com.webdrider.manager.action.user;

import java.util.ArrayList;
import java.util.List;

import com.common.dao.util.Criteria;
import com.common.manager.abstracts.AbstractManager;
import com.common.security.exceptions.DatabaseException;
import com.common.security.exceptions.ManagerException;
import com.common.security.exceptions.UserException;
import com.webdrider.dao.action.user.UserDao;
import com.webdrider.dao.interfaces.IUserDao;
import com.webdrider.manager.interfaces.IUserManager;
import com.webdrider.model.action.user.User;

public class UserManager extends AbstractManager<User> implements IUserManager {

	private IUserDao dao;

	public UserManager() {
		dao = new UserDao();
	}
	
	@Override
	protected IUserDao getDao() {
		return dao;
	}
	
	/**
	 * Get the user with the provided username and password. If any of those do not match 
	 * with any record, null will be returned. 
	 * 
	 * @param username
	 * @param password
	 * @return User
	 * @throws UserException 
	 * @throws ManagerException.USER_NOT_FOUND
	 * @throws ManagerException.MULTIPLE_USERS_FOUND
	 * @throws ManagerException.DATABASE_EXCEPTION
	 */
	public User getUser(String username, String password) throws ManagerException, UserException {
		try {
			List<Criteria> criterias = new ArrayList<Criteria>();
			criterias.add(new Criteria(User.USERNAME, username, true));
			criterias.add(new Criteria(User.PASSWORD, password, true));
			
			List<User> users = dao.getByCriteria(criterias);
			
			if (users.size() == 0) {
				throw new UserException(UserException.USER_NOT_FOUND);
			} else if (users.size() == 1) {
				return users.get(0);
			} else {
				throw new UserException(UserException.MULTIPLE_USERS_FOUND);
			}
		} catch (DatabaseException e) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		}
	}
	
	//TODO Trivial priority: add method comments
	public boolean exist(String username) throws ManagerException {
		try {
			Criteria criteria = new Criteria(User.USERNAME, username, true);
			boolean exist = dao.getByCriteria(criteria).size() > 0;
			
			return exist;
		} catch (DatabaseException e) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		}
	}

	public User login(String username, String password) throws ManagerException, UserException {
		try {
			User user = getUser(username, password);
			if (!user.isOnline()) {
				user.setOnline(true);
				dao.update(user);
			}
			
			return user;
		} catch (DatabaseException e) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		}
	}
	
	/**
	 * Logout the user with the provided userId.
	 * 
	 * @param userId
	 * @throws UserException 
	 * @throws ManagerException.DATABASE_EXCEPTION
	 */
	public void logout(Long id) throws ManagerException, UserException {
		try {
			User user = getById(id);
			if (user == null) {
				throw new UserException(UserException.USER_NOT_FOUND);
			}
			
			if (user.isOnline()) {
				user.setOnline(false);
				dao.update(user);
			}
		} catch (DatabaseException e) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		}
	}
}
